// ignore_for_file: must_be_immutable

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';

import 'custom_picker.dart';

enum FormType {
  text,
  edit,
  select,
  customSelect,
}

class FormWidget<T> extends StatefulWidget {
  FormType formType;

  ///通用属性值
  double width;

  double height;

  bool hasDividingLine;

  String leftText;

  TextStyle leftStyle;

  String contentText;

  TextStyle contentStyle;

  ///以下FormType.edit模式下有意义的值
  String editHintText;

  ValueChanged<String>? onEditChange;

  ///以下FormType.select模式下有意义的值
  List<String> dataList;

  ValueChanged<int>? onSelectChange;

  int selectIndex;

  String unSelectText;

  TextStyle unSelectStyle;

  ///
  VoidCallback? onSelectClick;

  TextInputType? keyboardType;

  List<TextInputFormatter>? inputFormatters;

  TextEditingController? textEditingController;

  FormWidget({
    super.key,
    required this.formType,
    double? width,
    double? height,
    this.hasDividingLine = true,
    required this.leftText,
    TextStyle? leftStyle,
    this.contentText = "",
    TextStyle? contentStyle,
    this.editHintText = "",
    this.onEditChange,
    List<String>? dataList,
    this.onSelectChange,
    this.selectIndex = -1,
    this.unSelectText = "",
    TextStyle? unSelectStyle,
    this.onSelectClick,
    this.keyboardType,
    this.inputFormatters,
    this.textEditingController,
  })  : width = width ?? double.infinity,
        height = height ?? 96.h,
        leftStyle = leftStyle ??
            TextStyle(color: const Color(0XFF6D6D6D), fontSize: 32.sp),
        contentStyle = contentStyle ??
            TextStyle(color: const Color(0XFF333333), fontSize: 32.sp),
        dataList = dataList ?? [],
        unSelectStyle = unSelectStyle ??
            TextStyle(color: const Color(0XFF6D6D6D), fontSize: 32.sp);

  FormWidget.text({
    Key? key,
    required String labelText,
    required String text,
    bool hasDividingLine = true,
  }) : this(
          key: key,
          formType: FormType.text,
          leftText: labelText,
          contentText: text,
          hasDividingLine: hasDividingLine,
        );

  FormWidget.edit({
    Key? key,
    required String labelText,
    String hintText = "",
    String? editText,
    bool hasDividingLine = true,
    ValueChanged<String>? onChange,
    TextInputType? keyboardType,
    List<TextInputFormatter>? inputFormatters,
    TextEditingController? textEditingController,
  }) : this(
          key: key,
          formType: FormType.edit,
          leftText: labelText,
          editHintText: hintText,
          contentText: editText ?? "",
          hasDividingLine: hasDividingLine,
          onEditChange: onChange,
          keyboardType: keyboardType ?? TextInputType.text,
          inputFormatters: inputFormatters ?? [],
          textEditingController: textEditingController,
        );

  FormWidget.select({
    Key? key,
    required String labelText,
    required List<String> dataList,
    int selectIndex = -1,
    String unSelectText = "请选择",
    TextStyle? selectStyle,
    TextStyle? unSelectStyle,
    bool hasDividingLine = true,
    ValueChanged<int>? onChange,
  }) : this(
          key: key,
          formType: FormType.select,
          leftText: labelText,
          contentText: selectIndex != -1 ? dataList[selectIndex] : '',
          contentStyle: selectStyle,
          selectIndex: selectIndex,
          unSelectText: unSelectText,
          unSelectStyle: unSelectStyle,
          hasDividingLine: hasDividingLine,
          dataList: dataList,
          onSelectChange: onChange,
        );

  FormWidget.customSelect({
    Key? key,
    required String labelText,
    required String selectText,
    String unSelectText = "请选择",
    TextStyle? selectStyle,
    TextStyle? unSelectStyle,
    bool hasDividingLine = true,
    VoidCallback? onSelectClick,
  }) : this(
          key: key,
          formType: FormType.customSelect,
          leftText: labelText,
          contentText: selectText,
          contentStyle: selectStyle,
          unSelectText: unSelectText,
          unSelectStyle: unSelectStyle,
          hasDividingLine: hasDividingLine,
          onSelectClick: onSelectClick,
        );

  @override
  State<FormWidget> createState() => _FormWidgetState();
}

class _FormWidgetState extends State<FormWidget> {
  //todo 尝试延迟初始化
  TextEditingController _controller = TextEditingController();

  @override
  void initState() {
    super.initState();
    initController();
  }

  void initController() {
    if (widget.formType == FormType.edit &&
        widget.textEditingController != null) {
      _controller = widget.textEditingController!;
      return;
    }
    _controller.text = widget.contentText;
  }

  @override
  Widget build(BuildContext context) {
    Widget bodyWidget = _builderBody();

    if (widget.hasDividingLine) {
      bodyWidget = _builderDividingLine(child: bodyWidget);
    }

    return SizedBox(
      width: widget.width,
      height: widget.height,
      child: bodyWidget,
    );
  }

  Widget _builderBody() {
    return Row(
      children: [
        SizedBox(
          width: 188.w,
          child: Text(
            widget.leftText,
            style: widget.leftStyle,
          ),
        ),
        Expanded(
          flex: 1,
          child: _builderContent(),
        ),
        _builderRightIcon(),
      ],
    );
  }

  Widget _builderDividingLine({
    required Widget child,
  }) {
    return Stack(
      alignment: AlignmentDirectional.center,
      children: [
        Positioned(child: child),

        ///分割线
        Positioned(
          left: 0,
          right: 0,
          bottom: 0,
          height: widget.hasDividingLine ? 2.h : 0,
          child: Container(
            color: const Color(0XFFF0F2F7),
          ),
        ),
      ],
    );
  }

  Widget _builderRightIcon() {
    if (widget.formType == FormType.text) {
      return Container();
    }

    if (widget.formType == FormType.edit) {
      return Visibility(
        visible: _controller.text.isNotEmpty,
        child: InkWell(
          onTap: () {
            setState(() {
              widget.contentText = "";
              _controller.text = "";
              widget.onEditChange?.call("");
            });
          },
          child: Icon(
            Icons.highlight_off,
            color: const Color(0XFFCECECE),
            size: 48.w,
          ),
        ),
      );
    }

    if (widget.formType == FormType.customSelect) {
      return InkWell(
        onTap: widget.onSelectClick,
        child: Icon(
          Icons.navigate_next,
          color: const Color(0XFFCECECE),
          size: 48.w,
        ),
      );
    }

    return InkWell(
      onTap: showSelectDialog,
      child: Icon(
        Icons.navigate_next,
        color: const Color(0XFFCECECE),
        size: 48.w,
      ),
    );
  }

  Widget _builderContent() {
    if (widget.formType == FormType.edit) {
      return TextField(
          controller: _controller,
          style: widget.contentStyle,
          onChanged: (value) {
            setState(() {
              widget.contentText = value;
              widget.onEditChange?.call(value);
            });
          },
          decoration: InputDecoration(
            border: InputBorder.none,
            hintText: widget.editHintText,
          ),
          inputFormatters: widget.inputFormatters,
          keyboardType: widget.keyboardType);
    }

    if (widget.formType == FormType.select) {
      bool isSelect = widget.selectIndex == -1;
      String text = isSelect ? widget.unSelectText : widget.contentText;
      TextStyle style = isSelect ? widget.unSelectStyle : widget.contentStyle;
      return InkWell(
        onTap: showSelectDialog,
        child: Text(
          text,
          style: style,
        ),
      );
    }

    if (widget.formType == FormType.customSelect) {
      String text = widget.contentText.isNotEmpty
          ? widget.contentText
          : widget.unSelectText;
      TextStyle style = widget.contentText.isNotEmpty
          ? widget.contentStyle
          : widget.unSelectStyle;
      return InkWell(
        onTap: widget.onSelectClick,
        child: Text(
          text,
          style: style,
        ),
      );
    }

    return Text(
      widget.contentText,
      style: widget.contentStyle,
    );
  }

  void showSelectDialog() {
    FocusManager.instance.primaryFocus?.unfocus();
    Get.bottomSheet(CustomPick(
      pickList: widget.dataList,
      confirmCallBack: (index) {
        setState(() {
          widget.contentText = widget.dataList[index];
          widget.selectIndex = index;
          widget.onSelectChange?.call(index);
        });
      },
      index: 0,
    ));
  }
}
